package suncertify.network;

import java.io.IOException;
import java.rmi.Remote;
import java.rmi.RemoteException;
import java.util.Vector;

import suncertify.db.DuplicateKeyException;
import suncertify.db.RecordNotFoundException;
import suncertify.db.Room;
import suncertify.ui.Subscriber;

/**
 * An interface that the application uses for polymorphism.  
 * It defines the actions that both a networked and non-networked server
 * should be able to perform.
 * @author Paul Wilhelm
 *
 */
public interface ServerInterface extends Remote{
	/**
	 * Reads a record from the file.
	 * is a record value.
	 * @param recNo - The record number to read
	 * @return A String[] where each element is the record value.
	 * @throws RecordNotFoundException
	 * @throws RemoteException
	 */
	public String [] read(int recNo) throws RecordNotFoundException, RemoteException;
	
	/**
	 * Modifies the fields of a record. The new value for field n 
	 * appears in data[n].
	 * @param recNo - The record number to update
	 * @param data - The data with which to update the record
	 * @throws RecordNotFoundException
	 * @throws RemoteException
	 */
	public void update(int recNo, String [] data)
	throws RecordNotFoundException, RemoteException;

	/**
	 * Deletes a record, making the record number and associated disk
	 * storage available for reuse. 
	 * @param recNo - The record to delete
	 * @throws RecordNotFoundException
	 * @throws RemoteException
	 */
	public void delete(int recNo) throws RecordNotFoundException, RemoteException;
	
	/**
	 * Finds a record in the database. A null value in criteria[n] matches any field
	 * value. A non-null  value in criteria[n] matches any field
	 * value that begins with criteria[n]. (For example, "Fred"
	 * matches "Fred" or "Freddy").
	 * @param criteria - A String[] describing the criteria.  Field n in the database
	 * is described by criteria[n].
	 * @return An array of record numbers that match the specified criteria.
	 * @throws RecordNotFoundException
	 * @throws RemoteException
	 */
	public int [] find(String [] criteria)
	throws RecordNotFoundException, RemoteException;
	
	/**
	 * Creates a new record in the database (possibly reusing a
	 * deleted entry).
	 * @param data - The data for the new record
	 * @return The record number of the new record.
	 * @throws DuplicateKeyException
	 * @throws RemoteException
	 */
	public int create(String [] data) throws DuplicateKeyException, RemoteException;
	
	/**
	 * Locks a record so that it can only be updated or deleted by this client.
	 * If the specified record is already locked, the current thread gives up
	 * the CPU and consumes no CPU cycles until the record is unlocked.
	 * @param recNo - The record number to lock
	 * @throws RecordNotFoundException
	 * @throws RemoteException
	 */
	public void lock(int recNo) throws RecordNotFoundException, RemoteException;
	
	/**
	 * Releases the lock on a record.
	 * @param recNo - The record number to release
	 * @throws RecordNotFoundException
	 */
	public void unlock(int recNo) throws RecordNotFoundException, RemoteException;
	
	/**
	 * Determines if a record is currently locked. Returns true if the
	 * record is locked, false otherwise.
	 * @param recNo - The record number to check
	 * @return Whether the record is locked or not
	 * @throws RecordNotFoundException
	 */
	public boolean isLocked(int recNo)
	throws RecordNotFoundException, RemoteException;
	
	/**
	 * Gets all the rooms in the database.
	 * @return A Vector of Room objects.
	 * @throws IOException
	 * @throws RemoteException
	 */
	public Vector<Room> getAllRooms() throws IOException, RemoteException;
	
	/**
	 * Receives a <code>Subscriber</code> object and adds it to it's list of subscriptions
	 * to notify.
	 * @param s - The Subscriber to add to the list of subscriptions
	 * @throws RemoteException
	 */
	public void subscribe(Subscriber s) throws RemoteException;
	
	/**
	 * Notifies all subscriptions that the data has changed.
	 * @throws RemoteException
	 */
	public void notifySubscriptions() throws RemoteException;
	
	/**
	 * Unsubscribes a <code>Subscriber</code> object from notifications.
	 * @param s - The Subscriber to unsubscribe
	 * @throws RemoteException
	 */
	public void unSubscribe(Subscriber s) throws RemoteException;
	
	/**
	 * Sets the name of the room given by the object that is making the data change.
	 * This is used to send back to the views so that they can know if they need to update 
	 * themselves or not.
	 * @param name - The name of the room.
	 * @throws RemoteException
	 */
	public void setRequestingName(String name) throws RemoteException;
	
	/**
	 * Sets the location of the room given by the object that is making the data change.
	 * This is used to send back to the views so that they can know if they need to update 
	 * themselves or not.
	 * @param location - The location of the room
	 * @throws RemoteException
	 */
	public void setRequestingLocation(String location) throws RemoteException;
}
